// CZ Virtual Actor 运行时 - 受 Orleans 启发
const std = @import("std");

/// Actor ID - 唯一标识一个 Actor
pub const ActorId = struct {
    type_name: []const u8,
    id: []const u8,
    
    pub fn hash(self: ActorId) u64 {
        var hasher = std.hash.Wyhash.init(0);
        hasher.update(self.type_name);
        hasher.update(self.id);
        return hasher.final();
    }
    
    pub fn eql(self: ActorId, other: ActorId) bool {
        return std.mem.eql(u8, self.type_name, other.type_name) and
               std.mem.eql(u8, self.id, other.id);
    }
};

/// Actor 元数据
pub const ActorMetadata = struct {
    id: ActorId,
    created_at: i64,
    last_accessed: i64,
    message_count: usize,
    state_version: usize,
};

/// Actor 状态
pub const ActorState = enum {
    Inactive,    // 未激活
    Activating,  // 激活中
    Active,      // 活跃
    Deactivating, // 失活中
};

/// Virtual Actor 基类
pub const VirtualActor = struct {
    id: ActorId,
    state: ActorState,
    metadata: ActorMetadata,
    mailbox: MessageQueue,
    allocator: std.mem.Allocator,
    
    pub fn init(allocator: std.mem.Allocator, id: ActorId) !*VirtualActor {
        const actor = try allocator.create(VirtualActor);
        actor.* = .{
            .id = id,
            .state = .Inactive,
            .metadata = .{
                .id = id,
                .created_at = std.time.timestamp(),
                .last_accessed = std.time.timestamp(),
                .message_count = 0,
                .state_version = 0,
            },
            .mailbox = try MessageQueue.init(allocator),
            .allocator = allocator,
        };
        return actor;
    }
    
    pub fn deinit(self: *VirtualActor) void {
        self.mailbox.deinit();
        self.allocator.destroy(self);
    }
    
    /// 激活 Actor
    pub fn activate(self: *VirtualActor) !void {
        if (self.state != .Inactive) return;
        
        self.state = .Activating;
        
        // 调用用户定义的激活方法
        try self.onActivate();
        
        self.state = .Active;
        self.metadata.last_accessed = std.time.timestamp();
    }
    
    /// 失活 Actor
    pub fn deactivate(self: *VirtualActor) !void {
        if (self.state != .Active) return;
        
        self.state = .Deactivating;
        
        // 调用用户定义的失活方法
        try self.onDeactivate();
        
        self.state = .Inactive;
    }
    
    /// 处理消息
    pub fn processMessage(self: *VirtualActor, message: Message) !void {
        // 确保 Actor 已激活
        if (self.state == .Inactive) {
            try self.activate();
        }
        
        // 更新元数据
        self.metadata.last_accessed = std.time.timestamp();
        self.metadata.message_count += 1;
        
        // 处理消息
        try self.onMessage(message);
    }
    
    // 虚函数 - 由子类实现
    pub fn onActivate(self: *VirtualActor) !void {
        _ = self;
    }
    
    pub fn onDeactivate(self: *VirtualActor) !void {
        _ = self;
    }
    
    pub fn onMessage(self: *VirtualActor, message: Message) !void {
        _ = self;
        _ = message;
    }
};

/// Actor 注册表
pub const ActorRegistry = struct {
    actors: std.AutoHashMap(ActorId, *VirtualActor),
    mutex: std.Thread.Mutex,
    allocator: std.mem.Allocator,
    
    pub fn init(allocator: std.mem.Allocator) !*ActorRegistry {
        const registry = try allocator.create(ActorRegistry);
        registry.* = .{
            .actors = std.AutoHashMap(ActorId, *VirtualActor).init(allocator),
            .mutex = .{},
            .allocator = allocator,
        };
        return registry;
    }
    
    pub fn deinit(self: *ActorRegistry) void {
        var iter = self.actors.valueIterator();
        while (iter.next()) |actor| {
            actor.*.deinit();
        }
        self.actors.deinit();
        self.allocator.destroy(self);
    }
    
    /// 获取或创建 Actor
    pub fn getOrCreate(
        self: *ActorRegistry,
        id: ActorId,
        create_fn: fn(std.mem.Allocator, ActorId) anyerror!*VirtualActor,
    ) !*VirtualActor {
        self.mutex.lock();
        defer self.mutex.unlock();
        
        if (self.actors.get(id)) |actor| {
            // Actor 已存在
            actor.metadata.last_accessed = std.time.timestamp();
            return actor;
        }
        
        // 创建新 Actor
        const actor = try create_fn(self.allocator, id);
        try self.actors.put(id, actor);
        
        // 激活 Actor
        try actor.activate();
        
        return actor;
    }
    
    /// 失活空闲 Actor
    pub fn deactivateIdle(self: *ActorRegistry, timeout_seconds: i64) !void {
        const now = std.time.timestamp();
        
        self.mutex.lock();
        defer self.mutex.unlock();
        
        var to_remove = std.ArrayList(ActorId).init(self.allocator);
        defer to_remove.deinit();
        
        var iter = self.actors.iterator();
        while (iter.next()) |entry| {
            const actor = entry.value_ptr.*;
            
            if (now - actor.metadata.last_accessed > timeout_seconds) {
                // 失活 Actor
                try actor.deactivate();
                try to_remove.append(entry.key_ptr.*);
            }
        }
        
        // 移除失活的 Actor
        for (to_remove.items) |id| {
            if (self.actors.fetchRemove(id)) |kv| {
                kv.value.deinit();
            }
        }
    }
}

/// Actor 系统配置
pub const ActorSystemConfig = struct {
    cluster_mode: bool = false,
    idle_timeout: i64 = 300,  // 5 分钟
    persistence: PersistenceConfig = .{},
    
    pub const PersistenceConfig = struct {
        type: PersistenceType = .Memory,
        connection_string: ?[]const u8 = null,
        
        pub const PersistenceType = enum {
            Memory,
            Redis,
            PostgreSQL,
            File,
        };
    };
};

/// Actor 系统
pub const ActorSystem = struct {
    registry: *ActorRegistry,
    config: ActorSystemConfig,
    allocator: std.mem.Allocator,
    cleanup_thread: ?std.Thread = null,
    running: bool = true,
    
    pub fn init(allocator: std.mem.Allocator, config: ActorSystemConfig) !*ActorSystem {
        const system = try allocator.create(ActorSystem);
        system.* = .{
            .registry = try ActorRegistry.init(allocator),
            .config = config,
            .allocator = allocator,
        };
        
        // 启动清理线程
        system.cleanup_thread = try std.Thread.spawn(.{}, cleanupLoop, .{system});
        
        return system;
    }
    
    pub fn deinit(self: *ActorSystem) void {
        self.running = false;
        
        if (self.cleanup_thread) |thread| {
            thread.join();
        }
        
        self.registry.deinit();
        self.allocator.destroy(self);
    }
    
    fn cleanupLoop(self: *ActorSystem) void {
        while (self.running) {
            std.time.sleep(60 * std.time.ns_per_s);  // 每分钟检查一次
            
            self.registry.deactivateIdle(self.config.idle_timeout) catch |err| {
                std.debug.print("Cleanup error: {}\n", .{err});
            };
        }
    }
};

/// 消息队列
pub const MessageQueue = struct {
    messages: std.ArrayList(Message),
    mutex: std.Thread.Mutex,
    
    pub fn init(allocator: std.mem.Allocator) !MessageQueue {
        return .{
            .messages = std.ArrayList(Message).init(allocator),
            .mutex = .{},
        };
    }
    
    pub fn deinit(self: *MessageQueue) void {
        self.messages.deinit();
    }
    
    pub fn enqueue(self: *MessageQueue, message: Message) !void {
        self.mutex.lock();
        defer self.mutex.unlock();
        
        try self.messages.append(message);
    }
    
    pub fn dequeue(self: *MessageQueue) ?Message {
        self.mutex.lock();
        defer self.mutex.unlock();
        
        if (self.messages.items.len == 0) return null;
        return self.messages.orderedRemove(0);
    }
};

/// 消息
pub const Message = struct {
    sender: ?ActorId,
    payload: []const u8,
    timestamp: i64,
};

// 测试
test "ActorRegistry" {
    const allocator = std.testing.allocator;
    
    var registry = try ActorRegistry.init(allocator);
    defer registry.deinit();
    
    const id = ActorId{ .type_name = "TestActor", .id = "test_001" };
    
    const actor = try registry.getOrCreate(id, VirtualActor.init);
    
    try std.testing.expectEqual(ActorState.Active, actor.state);
}

test "Actor deactivation" {
    const allocator = std.testing.allocator;
    
    var registry = try ActorRegistry.init(allocator);
    defer registry.deinit();
    
    const id = ActorId{ .type_name = "TestActor", .id = "test_001" };
    const actor = try registry.getOrCreate(id, VirtualActor.init);
    
    // 模拟空闲
    actor.metadata.last_accessed = std.time.timestamp() - 400;
    
    // 失活空闲 Actor
    try registry.deactivateIdle(300);
    
    // Actor 应该被移除
    try std.testing.expect(registry.actors.get(id) == null);
}
